package com.wind.common.interceptor;

import com.wind.common.utils.TraceLogContext;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

/**
 * 自定义拦截器
 * 该拦截器用于在请求处理前后添加一些共通的处理逻辑，比如记录请求时间、追踪请求ID等
 * 主要解决了微服务架构下请求追踪和日志管理的需求
 *
 * @author FengYin
 * @since 2024/8/30 09:11
 */
@Component
public class CustomHandlerInterceptor implements HandlerInterceptor {


    /**
     * 在请求处理之前执行
     * 该方法主要用来记录请求的开始时间，并生成或获取请求ID，然后将其添加到响应头中
     *
     * @param request  当前的HttpServletRequest对象，用于获取请求头中的traceId
     * @param response 当前的HttpServletResponse对象，用于设置响应头中的traceId
     * @param handler  当前请求的处理器对象
     * @return boolean值，决定是否继续执行请求处理(true表示继续，false表示中断)
     * @throws Exception 如果发生异常，则中断请求处理
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 设置请求时间
        TraceLogContext.setRequestTime();
        // 设置请求ID
        String traceId = request.getHeader("traceId");

        TraceLogContext.setTraceId(traceId);
        // 请求ID输出到响应头
        response.setHeader("x-trace-id", TraceLogContext.getTraceId());
        return true;
    }

    /**
     * 在请求处理完成之后执行
     * 该方法主要用于清理TraceLogContext中存储的请求ID和请求时间信息
     *
     * @param request  当前的HttpServletRequest对象
     * @param response 当前的HttpServletResponse对象
     * @param handler  当前请求的处理器对象
     * @param e        请求处理过程中可能抛出的异常
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception e) {
        // 移除请求ID
        TraceLogContext.removeTraceId();
        // 移除请求时间
        TraceLogContext.removeRequestTime();
    }


}
